home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programmer Power Tools
/
Programmer Power Tools.iso
/
dirutl
/
df_uz.arc
/
df.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-13
|
7KB
|
262 lines
/*
* DF - report disk space Ver. 1.1
*
* COPYRIGHT (C) 1989 by Urs Zurbuchen
* ALL RIGHTS RESERVED
*
* You are granted to the right to copy and
* distribute this program via any means
* as long as you don't remove this notice.
*
* However, you are specifically prohibited
* from charging, requesting any donations,
* and from distributing it with commercial
* products without prior written permission.
*
* ------------------------------------------------------------
*
* Displays a space usage statistic for all known drives in the
* systems. For join'ed drives their real free space is reported.
* Floppy sizes are only reported on request and if there is really
* a floppy in the drive. If there is none, the program continues
* without an error message.
*
* Example:
* C\:> df -f
* Total space Free space Drive
* 362'496 131'072 36% a:
* 2'060'288 1'155'072 56% c:
* 40'607'744 8'216'576 20% d:
* 67'051'520 5'554'176 8% e:
* 12'976'128 7'417'856 57% f:
* 518'912 518'912 100% g:
*
*
* Date: 16 January 1988
* Author: Urs Zurbuchen
*
* Compile:
* cl df.c (for Microsoft C)
*
* Revision history
* When Who What
* 30. 4.1989 zu Support for options -d and -f
* Prepared for submission to Usenet.
*
* Last released:
* 30. 4.1989 Ver. 1.1 Usenet, comp.binaries.ibm.pc
*
*---------------------------------------------------------------------------
*/
#include <stdio.h>
#include <dos.h>
#include <string.h>
#include <process.h>
#include <stdlib.h>
#include <setjmp.h>
long zehner[3] = { 1000000, 1000, 1 };
jmp_buf jb;
char error_handler[4] = { 0xb8, 0, 0, 0xcf };
#ifdef LINT_ARGS
char *basename( char * );
int main( int, char ** );
void print_number( long );
void print_statistics( unsigned char );
void setvector( unsigned int );
void Usage( char * );
#endif
int main( argc, argv )
int argc;
char **argv;
{
union REGS inregs, outregs;
struct SREGS segregs;
int drives, floppies;
int NoFloppies = 1, NoDisks = 0;
unsigned int olderr_offset, olderr_segment;
unsigned char i;
void print_statistics(), setvector();
/* initialize for error handling */
inregs.x.ax = 0x3524; /* get error handler vector */
intdosx( &inregs, &outregs, &segregs );
olderr_offset = outregs.x.bx;
olderr_segment= segregs.es;
setvector( (unsigned int)error_handler );
/* parse command line arguments */
if( argc > 1 ) {
for( i = (unsigned char) 1; (int)i < argc; i++ ) {
if( argv[i][0] == '-' ) {
switch( argv[i][1] ) {
case '?':
case 'h':
Usage( argv[0] );
exit( -1 );
break;
case 'f':
NoFloppies = 0;
break;
case 'd':
NoDisks = 1;
break;
default:
fprintf( stderr, "Unknown option %c\n",
argv[i][1] );
Usage( argv[0] );
break;
}
} else if( strlen( argv[i] ) == 2 && argv[i][1] == ':' ) {
print_statistics( (unsigned char)tolower( (int)argv[i][0] ) -
(int)'a' );
exit( 0 );
} else {
fprintf( stderr, "df: invalid argument %s\n",
argv[i] );
Usage( argv[0] );
exit( 1 );
}
}
}
/* determine number of logical drives in system */
inregs.h.ah = 0x19; /* get current disk */
intdos( &inregs, &outregs );
inregs.h.dl = outregs.h.al;
inregs.h.ah = 0x0e; /* select disk */
intdos( &inregs, &outregs );
drives = outregs.h.al;
/* we now have the number of logical drives. But, this number *
* might be wrong. It is just the value of the 'lastdrive=' *
* command in config.sys which defaults to five if not specified*
* We will have to test for the drives presence anyway. */
/* determine number of physical floppy drives in system */
int86( 0x11, &inregs, &outregs ); /* equipment determination */
floppies = ( outregs.h.al & 0x01 ) ? ( outregs.h.al >> 6 ) +1 : 0;
/* now print statistics */
/* - for floppies */
if( NoFloppies == 0 )
for( i = (unsigned char) 0; (int)i < floppies; i++ )
print_statistics( i );
/* - for harddisks */
if( NoDisks == 0 )
for( i = (unsigned char) 2; (int)i < drives; i++)
print_statistics( i );
/* restore vector for error handling */
inregs.x.ax = 0x2524; /* get error handler vector */
outregs.x.dx = olderr_offset;
segregs.ds = olderr_segment;
intdosx( &inregs, &outregs, &segregs );
return( 0 );
}
void print_statistics( drive )
unsigned char drive;
{
union REGS iregs, oregs;
long total, free;
static int firsttime = 0;
void print_number();
int checkdrive();
if( firsttime++ == 0 )
printf( "Total space Free space Drive\n" );
/* Try to print the statistics. If we try to read an inexistent *
* drive the operating system calls its 'fatal error' handler *
* (via INT 24h). Because we redirected this vector we will get *
* control again in case of an error. In such a case the program*
* just continues with the next drive. */
if( setjmp( jb ) != 0 )
return;
iregs.h.ah = 0x36; /* get disk space */
iregs.h.dl = drive +1;
intdos( &iregs, &oregs );
if( oregs.x.ax != 0xffff ) {
total = (long)oregs.x.ax * (long)oregs.x.cx * (long)oregs.x.dx;
free = (long)oregs.x.ax * (long)oregs.x.cx * (long)oregs.x.bx;
print_number( total );
print_number( free );
printf( "%3.1ld%% ", free / (total / 100L) );
printf( " %c:\n", drive + 'a' );
}
}
void print_number( n )
long n;
{
int i = 0, has_printed = 0;
long c;
/* if the number is greater than 999'999'999 we output it as it is */
if( n > 999999999 )
printf( "%ld", n );
else
while( i < 3 ) {
if( has_printed )
printf( "'" );
if( (c = n / zehner[i] ) >= 1L ) {
printf( (has_printed ? "%.3ld" : "%3.1ld"), c );
has_printed = 1;
} else
printf( has_printed ? "000" : " " );
n %= zehner[i++];
}
printf( " " );
}
void setvector( func )
unsigned int func;
{
union REGS inregs, outregs;
struct SREGS segregs;
segread( &segregs ); /* pick up segment registers */
inregs.x.ax = 0x2524; /* set our error handler vector */
inregs.x.dx = func;
intdosx( &inregs, &outregs, &segregs );
}
void Usage( prog )
char *prog;
{
fprintf( stderr, "Usage is:\n" );
fprintf( stderr, "%s: [-? | -h] [-f | -d] [d:]\n", strlwr( basename( prog )) );
fprintf( stderr, " -?, -h display this message\n" );
fprintf( stderr, " -f check floppies, too\n" );
fprintf( stderr, " -d do not check harddisks\n" );
fprintf( stderr, " d: check only drive d:\n" );
return;
}
char *basename( name )
char *name;
{
char *pos;
if( (pos = strrchr( name, '/' )) == NULL &&
(pos = strrchr( name, '\\' )) == NULL )
pos = name;
else
pos++;
return( pos );
}